/******************************************************************
 * Copyright @ 2024 广州牛师帮科技文化有限公司. All rights reserverd.
 * @file   src\hooks\theme\index.ts
 * @author Gim
 * @date   2024/07/19 11:53
 * @desc   UI主题风格控制
 ******************************************************************/

import { LiveStorage } from '@nsb/common-tools';
import { useTypedStorage } from '@nsb/common-tools/dist/hooks/useTypedStorage';
import { useCallback, useEffect, useState } from 'react';
import { CompactnessType as _CompactnessType, compactnessClassName, compactnessTypeOptions } from './CompactnessType';
import { LayoutType as _LayoutType, layoutTypeClassName, layoutTypeOptions } from './LayoutType';
import {
  LightType as _LightType,
  lightClassName as _lightClassName,
  lightConfigs as _lightConfigs,
  lightTypeOptions,
  system_dark
} from './LightType';
import { SmallScreen } from '../SmallScreen';

export namespace Theme {
  export const CompactnessType = _CompactnessType
  export type CompactnessType = _CompactnessType
  export const LightType = _LightType
  export type LightType = _LightType
  export const LayoutType = _LayoutType
  export type LayoutType = _LayoutType
  export interface IThemeOps {
    is_root?: boolean
  }

  export function use(opts?: IThemeOps) {

    const storage_key_1 = 'main_theme_light_type'
    const [_lightType] = useTypedStorage<LightType>('local', storage_key_1, lightTypeOptions);
    const lightType = _lightType ?? LightType.system;
    const [lightConfigs, set_lightConfigs] = useState(_lightConfigs)
    const [lightClassName, set_lightClassName] = useState(_lightClassName)

    const setLightType = useCallback((t: LightType) => LiveStorage.get('local').setItem(storage_key_1, '' + t), [])
    const toggleDark = useCallback(() => setLightType((Number(lightType) + 1) % (LightType.max + 1)), [setLightType, lightType])

    const storage_key_2 = 'main_theme_compactness_type'
    const [compactnessType] = useTypedStorage<CompactnessType>('local', storage_key_2, compactnessTypeOptions);
    const setCompactnessType = useCallback((t: CompactnessType) => LiveStorage.get('local').setItem(storage_key_2, '' + t), [])
    const toggleTight = useCallback(() => setCompactnessType((Number(compactnessType) + 1) % (CompactnessType.max + 1)), [setCompactnessType, compactnessType])

    const storage_key_3 = 'main_theme_layout_type'
    const [layoutType] = useTypedStorage<LayoutType>('local', storage_key_3, layoutTypeOptions);
    const setLayoutType = useCallback((t: LayoutType) => LiveStorage.get('local').setItem(storage_key_3, '' + t), [])
    const toggleLayout = useCallback(() => setLayoutType((Number(layoutType) + 1) % (LayoutType.max + 1)), [setLayoutType, layoutType])

    const small_screen = SmallScreen.use()
    const is_root = opts?.is_root;
    if (is_root) {
      const cls_1 = lightClassName[lightType!]
      const cls_2 = compactnessClassName[compactnessType!]
      const cls_3 = layoutTypeClassName[layoutType!]
      const root_ele = document.querySelector('html')
      if (root_ele) {
        root_ele.classList.remove(...Object.values(lightClassName))
        root_ele.classList.remove(...Object.values(compactnessClassName))
        root_ele.classList.remove(...Object.values(layoutTypeClassName))
        root_ele.classList.remove('small_screen')
        root_ele.classList.add(cls_1)
        root_ele.classList.add(cls_2)
        root_ele.classList.add(cls_3)
        if (small_screen) root_ele.classList.add('small_screen')
      }
    }
    useEffect(() => {
      const fn = () => {
        set_lightConfigs({ ..._lightConfigs })
        set_lightClassName({ ..._lightClassName })
      }
      system_dark?.addEventListener?.('change', fn)
      return () => system_dark?.removeEventListener?.('change', fn)
    }, [system_dark, set_lightConfigs, set_lightClassName])

    return {
      lightType,
      setLightType,
      theme: lightConfigs[lightType!],
      toggleDark,
      isDark: lightType === LightType.dark,
      isTight: compactnessType === CompactnessType.tight,
      toggleTight,
      layoutType,
      toggleLayout,
      setCompactnessType,
    }
  }
}